﻿using ExpressionPlotterControl;
using SMART_VIET_V01.Lib;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace SMART_VIET_V01
{
    public partial class frm_vedothi : Form
    {
        frm_main parent;
        public frm_vedothi()
        {
            InitializeComponent();
            expPlotter.MouseWheel += new MouseEventHandler(ExpPlotter_OnMouseWheel);
        }
        public frm_vedothi(frm_main parent)
        {
            this.parent = parent;
            InitializeComponent();
            expPlotter.MouseWheel += new MouseEventHandler(ExpPlotter_OnMouseWheel);
        }
        private void ExpPlotter_OnMouseWheel(object sender, MouseEventArgs e)
        {
            if (e.Delta > 0)
                expPlotter.ZoomIn();
            else if (e.Delta < 0)
                expPlotter.ZoomOut();
            expPlotter.Refresh();
        }


        #region Public Methods
        public int TrimCompareIgnoreCase(string a, string b)
        {
            int indexA = 0;
            int indexB = 0;
            while (indexA < a.Length && Char.IsWhiteSpace(a[indexA])) indexA++;
            while (indexB < b.Length && Char.IsWhiteSpace(b[indexB])) indexB++;
            int lenA = a.Length - indexA;
            int lenB = b.Length - indexB;
            while (lenA > 0 && Char.IsWhiteSpace(a[indexA + lenA - 1])) lenA--;
            while (lenB > 0 && Char.IsWhiteSpace(b[indexB + lenB - 1])) lenB--;
            if (lenA == 0 && lenB == 0) return 0;
            if (lenA == 0) return 1;
            if (lenB == 0) return -1;
            int result = String.Compare(a, indexA, b, indexB, Math.Min(lenA, lenB), true);
            if (result == 0)
            {
                if (lenA < lenB) result--;
                if (lenA > lenB) result++;
            }
            return result;
        }
        public void AddExpression(string text, Color color, string name, string xml)
        {
            bool check = true;
            TreeNode item;
            //if (treeModules.Nodes[1].Nodes.Count == 0)
            //{
            expPlotter.AddExpression((IEvaluatable)new Expression(text), color, true, xml);
            AddNode(treeModules.Nodes[1], text, name);
            //}
            //else
            //{
            //    foreach (TreeNode node in treeModules.Nodes[1].Nodes)
            //    {
            //        if (TrimCompareIgnoreCase(node.Name, text) == 0)
            //        {
            //            check = false;
            //        }
            //    }
            //    if (check)
            //    {
            //        expPlotter.AddExpression((IEvaluatable)new Expression(text), color, true);
            //        AddNode(treeModules.Nodes[1], text, name);
            //    }
            //    else
            //    {
            //        MessageBox.Show("Đồ thị đã vẽ rồi, hãy vẽ đồ thị khác.");
            //        return ;
            //    }
            //}
            treeModules.CollapseAll();
            treeModules.Refresh();
            treeModules.ExpandAll();
        }
        public void UpdateExpressions(exobj obj)
        {
            expPlotter.SetExpression(obj.index, obj.exIE);
            expPlotter.SetExpressionColor(obj.index, obj.color);
            expPlotter.SetExpressionVisibility(obj.index, obj.visible);
            expPlotter.SetExpressionXML(obj.index, obj.xml);
        }
        public void UpdateTrucDothi(double startX, double endX, double startY, double endY, int divX, int divY, int width, Color xy, Color xyLabel)
        {
            expPlotter.SetRangeX(startX, endX);
            expPlotter.SetRangeY(startY, endY);

            expPlotter.DivisionsX = divX;
            expPlotter.DivisionsY = divY;

            expPlotter.PenWidth = width;

            expPlotter.XYColor = xy;
            expPlotter.XYLabelColor = xyLabel;

            expPlotter.Refresh();
        }
        public void RemoveAllExpressions()
        {
            expPlotter.RemoveAllExpressions();
            treeModules.Nodes[1].Nodes.Clear();
        }
        public void SetRange(double startX, double endX, double startY, double endY)
        {
            expPlotter.SetRangeX(startX, endX);
            expPlotter.SetRangeY(startY, endY);
        }
        public void SetDivisions(int divX, int divY)
        {
            expPlotter.DivisionsX = divX;
            expPlotter.DivisionsY = divY;
        }
        public void SetPenWidth(int width)
        {
            this.expPlotter.PenWidth = width;
        }

        #endregion

        #region Private Methods

        private double GetR(double X, double Y)
        {
            return Math.Sqrt(X * X + Y * Y);
        }
        private double GetTheta(double X, double Y)
        {
            double dTheta;
            if (X == 0)
            {
                if (Y > 0)
                    dTheta = Math.PI / 2;
                else
                    dTheta = -Math.PI / 2;
            }
            else
                dTheta = Math.Atan(Y / X);

            //actual range of theta is from 0 to 2PI
            if (X < 0)
                dTheta = dTheta + Math.PI;
            else if (Y < 0)
                dTheta = dTheta + 2 * Math.PI;
            return dTheta;
        }

        private System.Drawing.Imaging.ImageFormat GetImageFormat(string filename)
        {
            string[] tempArray = filename.Split('.');
            string extension = tempArray[tempArray.Length - 1];
            switch (extension)
            {
                case "bmp":
                    return System.Drawing.Imaging.ImageFormat.Bmp;
                case "jpg":
                    return System.Drawing.Imaging.ImageFormat.Jpeg;
                case "gif":
                    return System.Drawing.Imaging.ImageFormat.Gif;
                case "png":
                    return System.Drawing.Imaging.ImageFormat.Png;
                case "tiff":
                    return System.Drawing.Imaging.ImageFormat.Tiff;
                case "wmf":
                    return System.Drawing.Imaging.ImageFormat.Wmf;
                default:
                    return System.Drawing.Imaging.ImageFormat.Bmp;
            }

        }

        #endregion



        private void btShowGrids_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            expPlotter.ToggleGrids();
            expPlotter.Refresh();
        }

        private void bttuyChinh_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (treeModules.SelectedNode.Tag.ToString() == "1")
            {
                Dictionary<string, string> bien = new Dictionary<string, string>();
                bien.Add("startX", expPlotter.Get_StartX().ToString());
                bien.Add("endX", expPlotter.Get_EndX().ToString());
                bien.Add("startY", expPlotter.Get_StartY().ToString());
                bien.Add("endY", expPlotter.Get_EndY().ToString());
                bien.Add("divX", expPlotter.DivisionsX.ToString());
                bien.Add("divY", expPlotter.DivisionsY.ToString());
                bien.Add("width", expPlotter.PenWidth.ToString());
                frm_tuychinhtruc frm = new frm_tuychinhtruc(this, bien, expPlotter.XYColor, expPlotter.XYLabelColor);
                frm.ShowDialog();
            }
            else if (treeModules.SelectedNode.Tag.ToString() != "2")
            {
                exobj obj = expPlotter.GetObjExpression(treeModules.SelectedNode.Index);
                obj.name = treeModules.SelectedNode.Text;
                frm_tuychinhdothi frm = new frm_tuychinhdothi(this, obj);
                frm.ShowDialog();
            }
        }

        private void btZoomOut_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            expPlotter.ZoomOut();
            expPlotter.Refresh();
        }
        private void btZoomIn_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            expPlotter.ZoomIn();
            expPlotter.Refresh();
        }

        private void btZoomInX_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            expPlotter.ZoomInX();
            expPlotter.Refresh();
        }

        private void btZoomOutX_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            expPlotter.ZoomOutX();
            expPlotter.Refresh();
        }

        private void btZoomInY_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            expPlotter.ZoomInY();
            expPlotter.Refresh();
        }

        private void btZoomOutY_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            expPlotter.ZoomOutY();
            expPlotter.Refresh();
        }

        private void bar_Chen_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            try
            {
                Bitmap bmp = expPlotter.GetGraphBitmap();
                parent.themHinhBaiGiang(bmp, "dothi");
            }
            catch (Exception ex)
            {

                Console.WriteLine(ex.Message);
            }
        }

        private void bar_tat_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            this.Close();
        }

        private void btXoa_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (treeModules.SelectedNode.Tag.ToString() != "1" && treeModules.SelectedNode.Tag.ToString() != "2" && treeModules.SelectedNode != null)
            {
                if (MessageBox.Show("Bạn có muốn xóa đồ thị này không ?", "Xóa", MessageBoxButtons.YesNo) == DialogResult.Yes)
                {
                    CheckBox B = (CheckBox)treeModules.SelectedNode.Tag;
                    B.Dispose();
                    expPlotter.RemoveExpressionAt(treeModules.SelectedNode.Index);
                    treeModules.Nodes[1].Nodes.RemoveAt(treeModules.SelectedNode.Index);
                    expPlotter.Refresh();
                    treeModules.CollapseAll();
                    treeModules.Refresh();
                    treeModules.ExpandAll();
                }
            }
        }

        private void btThemDothi_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            frm_tuychinhdothi frm = new frm_tuychinhdothi(this);
            frm.ShowDialog();
        }

        private void treeModules_AfterExpand(object sender, TreeViewEventArgs e)
        {
            ChangeDeleteButtonVisible(e.Node, true);
        }

        private void treeModules_AfterCollapse(object sender, TreeViewEventArgs e)
        {
            ChangeDeleteButtonVisible(e.Node, false);
        }
        void ChangeDeleteButtonVisible(TreeNode ParentNode, bool Visible)
        {
            foreach (TreeNode ChildNode in ParentNode.Nodes)
            {
                CheckBox B = (CheckBox)ChildNode.Tag;
                B.Name = ChildNode.Index.ToString();
                B.Location = new Point(ChildNode.Bounds.Location.X - 52, ChildNode.Bounds.Location.Y + 2);
                B.Width = 15;
                B.Height = 15;
                B.Visible = Visible;
            }
        }
        void AddNode(TreeNode ParentNode, String text, String name)
        {
            TreeNode Node = new TreeNode();
            Node.Text = name;
            Node.Name = text;
            Node.ImageIndex = 2;
            Node.SelectedImageIndex = 2;
            ParentNode.Nodes.Add(Node);
            CheckBox B = new CheckBox();
            B.Checked = true;
            B.Name = text;
            B.Parent = treeModules;
            B.Visible = false;
            B.CheckedChanged += new System.EventHandler(this.CheckedChanged);
            B.Tag = Node;
            Node.Tag = B;
        }

        private void CheckedChanged(object sender, EventArgs e)
        {
            CheckBox ch = (CheckBox)sender;
            int index = 0;
            Int32.TryParse(ch.Name, out index);
            if (ch.Checked)
                expPlotter.SetExpressionVisibility(index, true);
            else
                expPlotter.SetExpressionVisibility(index, false);

            expPlotter.Refresh();
        }

        private void btRefresh_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            expPlotter.RestoreDefaults();
            expPlotter.Refresh();
        }

        private void btDieuHuong_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (pnDieuhuong.Visible) pnDieuhuong.Visible = false;
            else pnDieuhuong.Visible = true;
        }

        private void btUp_Click(object sender, EventArgs e)
        {
            expPlotter.MoveUp(1);
            expPlotter.Refresh();
        }

        private void btRight_Click(object sender, EventArgs e)
        {
            expPlotter.MoveRight(1);
            expPlotter.Refresh();
        }

        private void btDown_Click(object sender, EventArgs e)
        {
            expPlotter.MoveDown(1);
            expPlotter.Refresh();
        }

        private void btLeft_Click(object sender, EventArgs e)
        {
            expPlotter.MoveLeft(1);
            expPlotter.Refresh();
        }

        double curX = 0;
        double curY = 0;
        private void expPlotter_MouseDown(object sender, MouseEventArgs e)
        {
            expPlotter.Cursor = Cursors.Hand;
            Dictionary<string, Double> cur = getCurXY(sender, e);
            curX = cur["X"];
            curY = cur["Y"];
            ttStatus.Caption = "Giữ và kéo chuột để di chuyển tọa độ đồ thị !";
        }

        private void expPlotter_MouseUp(object sender, MouseEventArgs e)
        {
            Dictionary<string, Double> cur = getCurXY(sender, e);

            if (cur["X"] > curX) expPlotter.MoveRight(1);
            if (cur["Y"] > curY) expPlotter.MoveUp(1);
            if (cur["X"] < curX) expPlotter.MoveLeft(1);
            if (cur["Y"] < curY) expPlotter.MoveDown(1);
            expPlotter.Refresh();
            ttStatus.Caption = "";
            expPlotter.Cursor = Cursors.Default;
        }

        private Dictionary<string, Double> getCurXY(object sender, MouseEventArgs e)
        {
            Dictionary<string, Double> result = new Dictionary<string, double>();
            double currentX = 0;
            double currentY = 0;
            currentX = (e.X - expPlotter.Width / 2) * expPlotter.ScaleX / expPlotter.Width * 2.25 + expPlotter.ForwardX;
            currentY = (expPlotter.Height / 2 - e.Y) * expPlotter.ScaleY / expPlotter.Height * 2.25 + expPlotter.ForwardY;
            if (this.expPlotter.GraphMode == GraphMode.Polar)
            {
                double r = GetR(currentX, currentY);
                double theta = GetTheta(currentX, currentY);
                currentX = r;
                currentY = theta;
            }
            currentX = (Double)((Int32)currentX);
            currentY = (Double)((Int32)currentY);

            result.Add("X", currentX);
            result.Add("Y", currentY);

            return result;
        }
    }
}
